package com.zlll.winner.service.mall;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zlll.winner.business.model.activity.ActivityManagement;
import com.zlll.winner.business.model.lhtUser.LhtUser;
import com.zlll.winner.business.model.mall.MallGoodsDetails;
import com.zlll.winner.business.model.mall.MallOrder;
import com.zlll.winner.business.model.mall.MallSeckillGoods;
import com.zlll.winner.business.model.mall.MallSelectGoods;
import com.zlll.winner.business.service.lhtUser.ILhtUserAddressService;
import com.zlll.winner.business.service.lhtUser.ILhtUserService;
import com.zlll.winner.business.service.mall.IMallGoodsDetailsService;
import com.zlll.winner.business.service.mall.IMallSeckillGoodsService;
import com.zlll.winner.business.service.mall.IMallSelectGoodsService;
import com.zlll.winner.business.vo.mall.MallGoodsDetailsVo;
import com.zlll.winner.business.vo.mall.MallOrderGoodsDetailVo;
import com.zlll.winner.business.vo.mall.MallOrderVo;
import com.zlll.winner.config.RabbitDelayConfig;
import com.zlll.winner.config.RedisLockWithIntegration;
import com.zlll.winner.enums.mall.MallEnum;
import com.zlll.winner.mapper.mall.MallOrderMapper;
import com.zlll.winner.business.service.mall.IMallOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zlll.winner.service.lhtUser.async.LhtUserAsyncService;
import com.zlll.winner.service.mall.async.MallOrderAsuncService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.Lock;


/**
 * <p>
 * 订单
 * 服务实现类
 * </p>
 *
 * @author qsx
 * @since 2019-10-08
 */
@Service
@Slf4j
public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder> implements IMallOrderService {

    @Autowired
    private MallOrderMapper mallOrderMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ILhtUserService lhtUserService;
    @Autowired
    private LhtUserAsyncService lhtUserAsyncService;

    @Autowired
    private RedisLockWithIntegration redisLockWithIntegration;
    @Autowired
    private IMallSeckillGoodsService mallSeckillGoodsService;
    @Autowired
    private IMallGoodsDetailsService mallGoodsDetailsService;
    @Autowired
    private IMallSelectGoodsService mallSelectGoodsService;

    @Autowired
    private MallOrderAsuncService mallOrderAsuncService;

    @Override
    public MallOrder saveMallOrder(MallOrder mallOrder) throws Exception {
        Lock lock = redisLockWithIntegration.getLock("mallGoods:" + mallOrder.getGoodsId(), 5, true);
        if (lock == null) {
            throw new Exception("兑换该商品太火爆了，请稍后再试");
        } else {

            LhtUser lhtUser = lhtUserService.getLhtUser(mallOrder.getAccount());

            if (lhtUser == null) {
                lock.unlock();
                throw new Exception("用户不存在，请先注册");
            }

            LhtUser user = lhtUserService.getLhtUser(mallOrder.getAccount());

            if (user.getResidueIntegral() < mallOrder.getIntegralNum()) {
                lock.unlock();
                throw new Exception("您的积分不足");
            }

            if (mallOrder.getSource().equals(1)) {
                //秒杀
                List<MallOrderGoodsDetailVo> list = mallOrderMapper.getMallOrderSeckillGoodsDetail(mallOrder.getSourceId(), mallOrder.getAccount());
                if (list.size() == 0) {
                    lock.unlock();
                    throw new Exception("商品不存在");
                } else {
                    MallOrderGoodsDetailVo mallOrderGoodsDetailVo = list.get(0);
                    if (mallOrderGoodsDetailVo.getInventoryNum() <= 0 || mallOrderGoodsDetailVo.getInventoryNum() < mallOrder.getNum()) {
                        lock.unlock();
                        throw new Exception("该商品库存不足，请联系商家补仓");
                    }

                    if (mallOrderGoodsDetailVo.getConvertedNum() >= mallOrderGoodsDetailVo.getNum()) {
                        lock.unlock();
                        throw new Exception("来晚一步，东西被抢光了");
                    }

                    if (mallOrderGoodsDetailVo.getMaxNum() <= mallOrderGoodsDetailVo.getCountNum()) {
                        lock.unlock();
                        throw new Exception("您已兑换过改商品了");
                    }
                }
            } else {
                //星选
                List<MallOrderGoodsDetailVo> list = mallOrderMapper.getMallOrderSelectGoodsDetail(mallOrder.getGoodsId(), mallOrder.getAccount());
                if (list.size() == 0) {
                    lock.unlock();
                    throw new Exception("商品不存在");
                } else {
                    MallOrderGoodsDetailVo mallOrderGoodsDetailVo = list.get(0);
                    if (mallOrderGoodsDetailVo.getInventoryNum() <= 0 || mallOrderGoodsDetailVo.getInventoryNum() < mallOrder.getNum()) {
                        lock.unlock();
                        throw new Exception("该商品库存不足，请联系商家补仓");
                    }

                    if (mallOrderGoodsDetailVo.getConvertedNum() >= mallOrderGoodsDetailVo.getNum()) {
                        lock.unlock();
                        throw new Exception("来晚一步，东西被抢光了");
                    }

                    if (mallOrderGoodsDetailVo.getMaxNum() <= mallOrderGoodsDetailVo.getCountNum()) {
                        lock.unlock();
                        throw new Exception("您已兑换过改商品了");
                    }
                }
            }
            try {
                mallOrder.setCreateTime(System.currentTimeMillis());
                mallOrder.setOrderNo(generateOrderNo());
                mallOrder.setStatus(MallEnum.StatusEnum.NOTPAY.val());
                mallOrderMapper.insert(mallOrder);
                mallOrderAsuncService.subtractInventoryNum(mallOrder.getSource(), mallOrder.getSourceId(), mallOrder.getGoodsId(), mallOrder.getNum());
                sendMallOrderToRabbitmq(mallOrder);
            } catch (Exception e) {

            } finally {
                lock.unlock();
            }
        }


        return mallOrder;
    }

    @Override
    public MallOrder orderPay(Long id, String address, String consignee, String contact) throws Exception {
        MallOrder mallOrder = mallOrderMapper.selectById(id);
        mallOrder.setStatus(MallEnum.StatusEnum.PAY.val());
        mallOrder.setUpdateTime(System.currentTimeMillis());
        mallOrder.setAddress(address);
        mallOrder.setConsignee(consignee);
        mallOrder.setContact(contact);
        updateById(mallOrder);
        LhtUser user = lhtUserService.getLhtUser(mallOrder.getAccount());

        if (user.getResidueIntegral() < mallOrder.getIntegralNum()) {
            throw new Exception("您的积分不足");
        }
        try {
            lhtUserAsyncService.changeSubtractIntegral(user.getId(), mallOrder.getIntegralNum());
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("积分减少失败：账号ID：{},积分：{}", user.getId(), mallOrder.getIntegralNum());
        }
        return mallOrder;
    }

    @Override
    public IPage<MallOrderVo> getMallOrderVoPage(String account, Integer pageSize, Integer pageNo, String goodsName, String orderNo, Integer status, Long startTime, Long endTime) {
        IPage<MallOrderVo> page = new Page<MallOrderVo>(pageNo, pageSize);
        List<MallOrderVo> list = mallOrderMapper.getMallOrderByCondition(account, goodsName, orderNo, status, startTime, endTime, page);
        page.setRecords(list);
        return page;
    }

    @Override
    public MallOrderVo getMallOrderVoById(Long id) {
        List<MallOrderVo> list = mallOrderMapper.getMallOrderVoById(id);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Boolean updateOrderStatus(Long id) throws Exception {
        MallOrder mallOrder = mallOrderMapper.selectById(id);
        if (mallOrder.getStatus().equals(MallEnum.StatusEnum.NOTPAY.val())) {
            mallOrder.setStatus(MallEnum.StatusEnum.fail.val());
            updateById(mallOrder);
            mallOrderAsuncService.increaseInventoryNum(mallOrder.getSource(), mallOrder.getSourceId(), mallOrder.getGoodsId(), mallOrder.getNum());
        }
        return true;
    }

    @Override
    public Boolean cancelStatus(Long id, Long userId) throws Exception {
        MallOrder mallOrder = mallOrderMapper.selectById(id);
        mallOrder.setUpdateUser(userId + "");
        mallOrder.setUpdateTime(System.currentTimeMillis());

        mallOrderAsuncService.increaseInventoryNum(mallOrder.getSource(), mallOrder.getSourceId(), mallOrder.getGoodsId(), mallOrder.getNum());
        if (mallOrder.getStatus().equals(MallEnum.StatusEnum.PAY.val())) {
            LhtUser user = lhtUserService.getLhtUser(mallOrder.getAccount());
            lhtUserAsyncService.changeIntegral(user.getId(), mallOrder.getIntegralNum());
        }
        mallOrder.setStatus(MallEnum.StatusEnum.cancel.val());

        return updateById(mallOrder);
    }

    @Override
    public Boolean updateReceivingInfo(Long id, Long userId, String address, String contact, String consignee) {
        MallOrder mallOrder = mallOrderMapper.selectById(id);
        mallOrder.setUpdateUser(userId + "");
        mallOrder.setUpdateTime(System.currentTimeMillis());
        mallOrder.setAddress(address);
        mallOrder.setContact(contact);
        mallOrder.setConsignee(consignee);
        return updateById(mallOrder);
    }

    public String generateOrderNo() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String data = simpleDateFormat.format(new Date().getTime());
        Integer sj = (int) ((Math.random() * 9 + 1) * 1000);
        return data + sj;
    }


    /**
     * 发送活动状态到rabbitmq
     */
    private void sendMallOrderToRabbitmq(MallOrder order) {
        Long time = 1800000l;
        log.info("订单状态延时刷新,当前的活动是：id={},延时时间={}", order.getId(), time);
        //第一个参数是前面RabbitMqConfig的交换机名称 第二个参数的路由名称 第三个参数是传递的参数 第四个参数是配置属性
        this.rabbitTemplate.convertAndSend(
                RabbitDelayConfig.MALL_DELAY_EXCHANGE,
                RabbitDelayConfig.MALL_DELAY_ROUTING_KEY,
                order,
                message -> {
                    // 指定延迟时间(单位是毫秒)
                    message.getMessageProperties().setDelay(time.intValue());
                    return message;
                });
    }

}
